package creature;

import java.awt.BorderLayout;
import java.awt.Frame;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import audio.Audio;
import boids.*;
import processing.core.*;
import processing.opengl.*;
import toolib.util.GraphicsUtil;
import toxi.geom.Vec2D;


public class CreatureTest extends PApplet {
	public static final int	GAME_WIDTH			= 1280;
	public static final int	GAME_HEIGHT			= 800;
	private final int		NUM_CREATURES		= 2;

	private int				numPlayersPerTeam	= NUM_CREATURES / 2;
	private World			world;
	private DrawnPath		pathRecordingBuffer;
	private Creature		pathAssignBuffer;

	private Creature[]		teamOne;
	private Creature[]		teamTwo;

	private Base			baseOne;
	private Base			baseTwo;

	private boolean			drawing				= false;

	private Background		_background;
	private int				_backgroundTick		= 0;

	public void setup () {
		//size (GAME_WIDTH, GAME_HEIGHT, OPENGL);
		size(screen.width, screen.height, OPENGL);

		Audio.init (this);

		_background = new Background (this);
		_background.generate ();

		world = new World (width, height);
		pathRecordingBuffer = new DrawnPath (2.5f);

		baseOne = new Base (Base.MARGIN, height / 2, loadImage ("base.png"),
				loadImage ("jellyfish/flag1.png"));
		baseTwo = new Base (width - Base.MARGIN, height / 2,
				loadImage ("base.png"), loadImage ("jellyfish/flag2.png"));

		teamOne = new Creature[numPlayersPerTeam];
		teamTwo = new Creature[numPlayersPerTeam];

		for (int i = 0; i < numPlayersPerTeam; i++){
			teamOne[i] = new Creature (new Vec2D (random (width),
					random (height)));
			teamOne[i].setEnvironment (world);
			teamOne[i].setMode (SteeringBehaviors.PATHFOLLOW);

			teamTwo[i] = new Creature (new Vec2D (random (width),
					random (height)));
			teamTwo[i].setEnvironment (world);
			teamTwo[i].setMode (SteeringBehaviors.PATHFOLLOW);
		}

		loadAndAssignTextures ();
	}

	private void loadAndAssignTextures () {
		PImage ringImage = loadImage ("jellyfish/ring.png");
		PImage bombRingImage = loadImage ("jellyfish/bombRing.png");

		PImage centerImage1 = loadImage ("jellyfish/center010.png");
		PImage centerImage2 = loadImage ("jellyfish/center021.png");
		PImage centerImage3 = loadImage ("jellyfish/center022.png");
		PImage speedImage = loadImage ("jellyfish/speed.png");

		PImage flag1 = loadImage ("jellyfish/flag1.png");
		PImage flag2 = loadImage ("jellyfish/flag2.png");

		for (int i = 0; i < numPlayersPerTeam; i++){
			teamOne[i].setRingImage (ringImage);
			teamOne[i].setBombRingImage (bombRingImage);
			teamOne[i].setCenterImage1 (centerImage1);
			teamOne[i].setCenterImage2 (centerImage2);
			teamOne[i].setSpeedImage (speedImage);
			teamOne[i].setFlagImage (flag2);

			teamTwo[i].setRingImage (ringImage);
			teamTwo[i].setBombRingImage (bombRingImage);
			teamTwo[i].setCenterImage1 (centerImage1);
			teamTwo[i].setCenterImage2 (centerImage3);
			teamTwo[i].setSpeedImage (speedImage);
			teamTwo[i].setFlagImage (flag1);
		}
	}

	public void draw () {
		imageMode (CENTER);

		_backgroundTick++;

		if (_backgroundTick == 4){
			_background.generate ();
			_backgroundTick = 0;
		}
		_background.render ();

		boolean renderFlagOne = true;
		boolean renderFlagTwo = true;

		for (int i = 0; i < teamOne.length; i++){
			if (teamOne[i].getGameState () == Creature.STATE_HASFLAG){
				renderFlagTwo = false;
				break;
			}
		}
		for (int i = 0; i < teamTwo.length; i++){
			if (teamTwo[i].getGameState () == Creature.STATE_HASFLAG){
				renderFlagOne = false;
				break;
			}
		}
		if (renderFlagTwo){
			for (int i = 0; i < teamOne.length; i++){
				if (teamOne[i].getGameState () == Creature.STATE_NORMAL){
					if (teamOne[i].getPosition ().distanceTo (
							baseTwo.position ()) < 50){
						teamOne[i].setGameState (Creature.STATE_HASFLAG);
						break;
					}
				}
			}
		}
		if (renderFlagOne){
			for (int i = 0; i < teamTwo.length; i++){
				if (teamTwo[i].getGameState () == Creature.STATE_NORMAL){
					if (teamTwo[i].getPosition ().distanceTo (
							baseOne.position ()) < 50){
						teamTwo[i].setGameState (Creature.STATE_HASFLAG);
					}
				}
			}
		}

		baseOne.render (g, renderFlagOne);
		baseTwo.render (g, renderFlagTwo);

		if (!drawing){
			for (int i = 0; i < numPlayersPerTeam; i++){
				teamOne[i].update ();
				teamTwo[i].update ();
			}
		}

		world.render (g);

		if (pathRecordingBuffer != null){
			pathRecordingBuffer.render (g);
		}

		for (int i = 0; i < numPlayersPerTeam; i++){
			teamOne[i].render (this);
			teamTwo[i].render (this);
		}
	}

	public void keyPressed () {
		switch (key) {
			case '1':
				if (pathAssignBuffer != null)
					pathAssignBuffer.setGameState (Creature.STATE_NORMAL);
				break;
			case '2':
				if (pathAssignBuffer != null)
					pathAssignBuffer.setGameState (Creature.STATE_WALL);
				break;
			case '3':
				if (pathAssignBuffer != null)
					pathAssignBuffer.setGameState (Creature.STATE_SPEED);
				break;
			case '4':
				if (pathAssignBuffer != null)
					pathAssignBuffer.setGameState (Creature.STATE_BOMB);
				break;
			case '5':
				if (pathAssignBuffer != null)
					pathAssignBuffer.setGameState (Creature.STATE_HASFLAG);
				break;
			case 'a':
				Audio.playBlub ();
				break;
			case 's':
				Audio.playPuck ();
				break;
			case 'd':
				Audio.playWiggle ();
				break;
		}
	}

	public void mousePressed () {
		drawing = true;
		Vec2D mousePos = new Vec2D (mouseX, mouseY);

		pathAssignBuffer = getNearestCreature (mousePos);
		pathAssignBuffer.resetPathFollowIndex ();

		pathRecordingBuffer = (DrawnPath) world
				.getPathForBoid (pathAssignBuffer);
		if (pathRecordingBuffer == null){
			pathRecordingBuffer = new DrawnPath (2.5f);
		}

		pathRecordingBuffer.clear ();
		pathRecordingBuffer.addPoint (mousePos);

	}

	public void mouseDragged () {
		pathRecordingBuffer.addPoint (new Vec2D (mouseX, mouseY));
	}

	public void mouseReleased () {
		drawing = false;
		world.assignPathToBoid (pathAssignBuffer, pathRecordingBuffer);
		pathAssignBuffer.setPathFollowIndexToClosestPoint (pathRecordingBuffer);
	}

	public Creature getNearestCreature (Vec2D _pos) {
		float minDist = -1.0f;
		int minIndex = -1;
		int team = -1;

		for (int i = 0; i < teamOne.length; i++){
			float d = _pos.sub (teamOne[i].getPosition ()).magSquared ();
			if (minDist == -1.0f || d < minDist){
				minDist = d;
				minIndex = i;
				team = 1;
			}
		}

		for (int i = 0; i < teamTwo.length; i++){
			float d = _pos.sub (teamTwo[i].getPosition ()).magSquared ();
			if (minDist == -1.0f || d < minDist){
				minDist = d;
				minIndex = i;
				team = 2;
			}
		}

		if (team == 1){
			return teamOne[minIndex];
		}else{
			return teamTwo[minIndex];
		}
	}
	
	public static void main (String[] args) {
		Frame f		= new Frame ("ctf tangible", GraphicsUtil.configuration (0));
		PApplet a	= new CreatureTest ();
		a.init ();
		a.start ();
		f.setUndecorated (true);
		
		f.setLayout (null);
		GraphicsUtil.setFullScreen (0, f, true);
		f.add (a);

		f.addWindowListener (new WindowAdapter () {
			public void windowClosing (WindowEvent ev) {
				System.exit (0);
			}
		});
		
		a.addKeyListener (new KeyAdapter () {
			public void keyPressed (KeyEvent ev) {
				if (ev.getKeyCode () == KeyEvent.VK_ESCAPE) {
					System.exit (0);
				}
			}
		});
	}

//	public static void main (String args[]) {
//		PApplet.main (new String[] { "--present""creature.CreatureTest"});
//	}
}
